﻿// ----------------------------------------------------------------
//  Copyright (C) 2018 奇瑞信息有限公司
//  版权所有。 
//  文件名：MenuRoleService
//  文件功能描述：菜单角色 后台接口
//  创建人：陈明华
//  创建时间：2018-12-06
// ----------------------------------------------------------------
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.EntityFrameworkCore.Extensions;
using Abp.Linq.Extensions;
using Abp.Runtime.Caching;
using Abp.UI;
using AutoMapper;
using Castle.Core.Internal;
using CheryABP.AdoContext;
using CheryABP.ApiAttribute;
using CheryABP.Common;
using CheryABP.Enum;
using CheryABP.Extensions;
using CheryABP.Interceptor;
using CheryABP.SystemSetitng;
using CheryABP.SystemSetting.LoginAPI.Dto;
using CheryABP.SystemSetting.MeneRoleAPI.Dto;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CheryABP.SystemSetting.MeneRoleAPI
{
   

    /// <summary>
    /// 菜单角色管理
    /// </summary>
    public class MenuRoleService: CheryABPAppServiceBase
    {
        private readonly IRepository<system_menu> _menuRoleRepository;
        private readonly IRepository<system_role> _roleRepository;
        private readonly IRepository<system_department> _departRepository;
        private readonly IRepository<system_role_action> _actionRepository;
        private readonly IRepository<system_login> _loginRepository;
        private readonly IRepository<system_role_user> _roleUserRepository;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private ISession _session => _httpContextAccessor.HttpContext.Session;
        /// <summary>
        /// 构造函数自动注入
        /// </summary>
        /// <param name="menuRoleRepository"></param>
        /// <param name="roleRepository"></param>
        /// <param name="departRepository"></param>
        /// <param name="actionRepository"></param>
        /// <param name="loginRepository"></param>
        /// <param name="roleUserRepository"></param>
        /// <param name="httpContextAccessor"></param>
        public MenuRoleService(IRepository<system_menu> menuRoleRepository,IRepository<system_role> roleRepository, 
            IRepository<system_department> departRepository,IRepository<system_role_action> actionRepository,
            IRepository<system_login> loginRepository, IRepository<system_role_user> roleUserRepository,IHttpContextAccessor httpContextAccessor)
        {
            _menuRoleRepository = menuRoleRepository;
            _roleRepository = roleRepository;
            _departRepository = departRepository;
            _actionRepository = actionRepository;
            _loginRepository = loginRepository;
            _roleUserRepository = roleUserRepository;
            _httpContextAccessor = httpContextAccessor;
        }


        #region 菜单操作
        /// <summary>
        /// 查询所有菜单(后台拼接固定格式)
        /// </summary>
        /// <returns></returns>
        public string GetAllMenu()
        {

            StringBuilder sb = new StringBuilder();
            //查询菜单前3条数据，
            var topThree = _menuRoleRepository.GetAllList(o => o.stop_status == 0).Take(3).OrderByDescending(o=>o.id).ToList();//查询一级菜单
            string redirectUrl = string.Empty;
            if (topThree[0].system_rank == 2)
            {
                redirectUrl = topThree[0].link_url;
            }
            if (topThree[0].system_rank == 3)
            {
                redirectUrl = topThree[0].link_url;
            }
            var listOne =  _menuRoleRepository.GetAllList(o => o.stop_status == 0 && o.system_rank == 1);//查询一级菜单
            sb.Append(" routes: [");
            sb.Append("{ path: '/', redirect: '" + redirectUrl + "' },");
            for (int i = 0; i < listOne.Count; i++)  
            {
                var listTwoAll= _menuRoleRepository.GetAllList(o => o.stop_status == 0 && o.parent_id == listOne[i].id && o.system_rank == 2);//根据上面菜单的id遍历下面的子菜单
                
                sb.Append("{");
                sb.Append("path:'" + listOne[i].link_url + "',");
                sb.Append("name:'" + listOne[i].menu_name + "',");
                sb.Append("icon:'" + listOne[i].icon_url + "',");
              
             
                sb.Append(" routes: ["); 
                for (int j = 0; j < listTwoAll.Count; j++)
                {
                   
                    sb.Append("{");
                    sb.Append("path:'" + listTwoAll[j].link_url + "',");
                    sb.Append("name:'" + listTwoAll[j].menu_name + "',");
                    sb.Append("component:'" + listTwoAll[j].component_url + "',");
                    var listThreeAll = _menuRoleRepository.GetAllList(o => o.stop_status == 0 && o.parent_id == listTwoAll[j].id && o.system_rank == 3);//根据上面菜单的id遍历下面的子菜单
                    if (listThreeAll.Count > 0)
                    {
                        sb.Append("routes: [");
                        sb.Append("{ path: '" + listTwoAll[j].link_url + "', redirect: '" + listThreeAll[0].link_url + "' },");
                    }
                    for (int k = 0; k < listThreeAll.Count; k++)
                    {
                        sb.Append("{");
                        sb.Append("path:'" + listThreeAll[k].link_url + "',");
                        sb.Append("name:'" + listThreeAll[k].menu_name + "',");
                        sb.Append("component:'" + listThreeAll[k].component_url + "',");
                        sb.Append("},");
                    }
                    if (listThreeAll.Count > 0)
                    {
                        sb.Append("],");
                    }
                    sb.Append("},");
                }
                sb.Append("],");
                sb.Append("},");
            }
            sb.Append("],");
            return sb.ToString();
        }


        /// <summary>
        /// 新增菜单
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected system_menu InsertMenu(MenuDtoInput input)
        {
            try
            {
                var newMenu = new system_menu {
                    menu_name=input.menu_name,
                    system_rank=input.system_rank,
                    parent_id=input.parent_id,
                    memo=input.icon_url,
                    sort_id=input.sort_id,
                    link_url=input.link_url,
                    component_url=input.component_url,
                    add_time = DateTime.Now, duty_name = ""
                };
                return _menuRoleRepository.Insert(newMenu);
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
          
        }
        /// <summary>
        /// 查询菜单 ：根据层级和权限,带原始的操作类型   ps:最后修改于2018-12-20
        /// </summary>
        /// <param name="system_rank">菜单层级system_rank=0或者空,查询全部，参数1：一级菜单；2二级菜单，类推。。。</param>
        /// <param name="type">type=0:查询不带权限的所有菜单，type=1:查询有权限的菜单</param>
        /// <returns></returns>
        public List<MenuRoleDtoOutput> GetParentMenu(int system_rank,string type)
        {
            //ISession _session = _httpContextAccessor.HttpContext.Session;
            //AdminInfo = AbpSessionExtension.GetObjectFromJson<system_login>(_session, DTKeys.SESSION_ADMIN_INFO);
            //if (AdminInfo == null)
            //{
            //    var response = _httpContextAccessor.HttpContext.Response;
            //    response.Redirect("/404.html");
            //}
            int num = 0;
            if (!int.TryParse(type, out num))
            {
                throw new UserFriendlyException("参数type请传入数字0或1");
            }
            //if (system_rank == 0)
            try
            {
                var model = _menuRoleRepository.GetAllList(o => o.stop_status == 0);
                List<MenuRoleDtoOutput> listMenu = new List<MenuRoleDtoOutput>();
                string[] arryAction = { };
                foreach (var m in model)
                {
                    MenuRoleDtoOutput menuRole = new MenuRoleDtoOutput();
                    List<actionC> actionC = new List<actionC>();
                    arryAction = m.action_type.Split(',');
                    if (arryAction.Length < 1)
                    {
                        continue;
                    }
                    foreach (var i in arryAction)
                    {
                        actionC ac = new actionC();
                        ac.action_type = i;
                        actionC.Add(ac);
                    }
                    menuRole.id = m.id;
                    menuRole.menu_name = m.menu_name;
                    menuRole.system_rank = m.system_rank;
                    menuRole.parent_id = m.parent_id;
                    menuRole.add_time = m.add_time;
                    menuRole.memo = m.memo;
                    menuRole.stop_status = m.stop_status;
                    menuRole.icon_url = m.icon_url;
                    menuRole.sort_id = m.sort_id;
                    menuRole.link_url = m.link_url;
                    menuRole.component_url = m.component_url;
                    menuRole.duty_name = m.duty_name;

                    menuRole.action = actionC;
                    listMenu.Add(menuRole);
                }
                return listMenu;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
    
            }



        #endregion

        #region --------------------------------------角色----------------------------------------------
        /// <summary>
        ///【角色管理】  新增角色,选择菜单，分配菜单操作权限 ps：修改于2018-12-21 09：01
        /// </summary>
        /// <param name="input">备注：menu_ids：选择的菜单id</param>
        /// <returns></returns>
        //[UnitOfWork(IsDisabled = true)]
        public string InsertRole(RoleDtoInput input)
        {
            try
            {
                var role = ObjectMapper.Map<system_role>(input);
                int id = _roleRepository.InsertAndGetId(role);//实体不能有id
                int num = 0;
                //菜单id 写入 system_role_menu
                foreach (var i in input.role_action_info)
                {
                    for (var j = 0; j < i.action.Count; j++)
                    {
                        var action_mod = new system_role_action { role_id = id, menu_id = i.menu_id, action_type= i.action[j].action_type};
                        num = _actionRepository.InsertAndGetId(action_mod);
                    }
                }
                if (num > 0)
                {
                    return "创建角色成功";
                }
                throw new UserFriendlyException("创建角色失败");
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
        }

        /// <summary>
        ///【角色管理】  分页 角色展示列表（根据角色名称查询列表）ps:最后修改于2018-12-20
        /// </summary>
        /// <param name="roleName">不填写时查询全部</param>
        /// <param name="input">分页</param>
        /// <returns></returns>
        public PageOutputDto<List<RoleDtoOutput>> GetAllRoleList(string roleName, PageInputDto input)
        {
            try
            {
                string where = string.IsNullOrEmpty(roleName) ? "" : $" and t1.role_name ='{roleName}'";
                string sql = $@"select t1.id,role_name,t1.memo,t1.add_date,role_type,t2.menu_id,t2.action_type
                from system_role t1   
                LEFT JOIN system_role_action t2
                ON  t2.role_id = t1.id
                WHERE t1.stop_status = 0 AND t2.stop_status= 0 {where}";
                DataTable dt = MySqlConn.Query(sql).Tables[0];
                var modelRole = _roleRepository.GetAllList(o => o.stop_status == 0)
                    .WhereIf(!string.IsNullOrEmpty(roleName), x => x.role_name == roleName);



                List<RoleDtoOutput> l_roleDto = new List<RoleDtoOutput>();
                foreach (var m in modelRole)
                {
                    List<Menu_Info> menuInfo = new List<Menu_Info>();
                    RoleDtoOutput role = new RoleDtoOutput();
                    role.role_name = m.role_name;
                    role.role_type = m.role_type;
                    role.add_date = m.add_date;
                    role.memo = m.memo;
                    role.id = m.Id;
                    //匹配角色和菜单
                    var roleMenu = dt.AsEnumerable().Where(o=>int.Parse(o["id"].ToString()) == m.Id).
                        Select(i=>new { id=int.Parse(i["id"].ToString()),role_name=i["role_name"].ToString(),
                            memo =i["memo"].ToString(),
                            role_type =int.Parse(i["role_type"].ToString()),
                            action_type =i["action_type"].ToString(),
                            add_date =i["add_date"].ToString(),
                            menu_id = int.Parse(i["menu_id"].ToString())}).Distinct().ToList();
                    List<int> ids = new List<int>();
                    foreach (var x in roleMenu)
                    {
                        List<MenuActionOut> menuAction = new List<MenuActionOut>();
                        Menu_Info minfo = new Menu_Info();
                        if (ids.Contains(x.menu_id))
                        {
                            continue;
                        }
                        minfo.menu_id = x.menu_id;
                        ids.Add(minfo.menu_id);
                        //匹配角色和菜单
                        var actionMenu = roleMenu.Where(o => o.menu_id == x.menu_id).ToList();
                        foreach (var z in actionMenu)
                        {
                            MenuActionOut ma = new MenuActionOut();
                            ma.action_type = z.action_type;
                            menuAction.Add(ma);
                            minfo.menu_action = menuAction;
                        }
                        menuInfo.Add(minfo);
                    }
                    role.menu_info = menuInfo;
                    l_roleDto.Add(role);
                }
                int totalCount = l_roleDto.Count;
                int skipNum = input.pageSize * input.pageIndex;
                var listPageData = l_roleDto.Take(input.pageSize).Skip(skipNum).OrderBy(i=>i.id).ToList();
                return new PageOutputDto<List<RoleDtoOutput>> { totalCount = totalCount, items = listPageData }; ;
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
        }

        /// <summary>
        ///【角色管理】  修改角色(id 传实际值) ps：修改于2018-12-21 09：01
        /// </summary>
        /// <param name="input">RoleDtoInput 参考swagger下方model说明</param>
        /// <returns></returns>
        public string UpdateRole(RoleDtoInput input)
        {
            var model = _roleRepository.Get(input.Id);
            model.role_name = input.role_name;
            model.memo = input.memo;
            model.role_type = input.role_type;

            _actionRepository.Delete(x => x.role_id == input.Id);
            //菜单id 写入 system_role_menu
            int num = 0;
            foreach (var i in input.role_action_info)
            {
                for (var j = 0; j < i.action.Count; j++)
                {
                    var action_mod = new system_role_action { role_id = input.Id, menu_id = i.menu_id, action_type = i.action[j].action_type };
                    num = _actionRepository.InsertAndGetId(action_mod);
                }
            }
            if (num > 0)
            {
                return "修改角色成功";
            }
            throw new UserFriendlyException("修改角色失败");
        }
        /// <summary>
        ///【角色管理】 停用/启用角色 ps:最后修改于 2018-12-21 15：00
        /// </summary>
        /// <param name="type">停用1，启用0</param>
        /// <param name="id">该条数据的id（角色id）</param>
        public string StopStartRole(int type,int id)
        {
            string ope = type == 0 ? "启用" : "停用";
            _roleRepository.Update(id, x=>x.stop_status= type);

            var modelRoleAction = _actionRepository.GetAllList(x=>x.role_id == id);
            modelRoleAction.ForEach(x => _actionRepository.Update(x.Id, o=>x.stop_status = type));

            var modelRoleUser = _roleUserRepository.GetAllList(x => x.role_id == id);
            modelRoleUser.ForEach(x => _roleUserRepository.Update(x.Id, o => x.stop_status = type));

            return $"{ope}角色成功";
        }
        #endregion

        /// <summary>
        /// 查询所有部门信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<system_department>> GetALLDep()
        {
            return await _departRepository.GetAllListAsync(o=>o.stop_status==0);
        }

        #region--------------------------------------用户管理----------------------------------------------

        /// <summary>
        ///【用户管理】 分页查询用户列表
        /// </summary>
        /// <param name="strFilter">查询条件：姓名、工号</param>
        /// <param name="input">PagedInputDto </param>
        /// <returns></returns>
        public PageOutputDto<DataTable> GetAllUserPage(string strFilter,PageInputDto input)
        {
            try
            {
                //var userRole = _roleUserRepository.GetAll().WhereIf(!string.IsNullOrEmpty(strFilter), x => x.user_name == strFilter);
                //var query = _loginRepository.GetAll().OrderBy(x => x.Id).Take(20)
                //.WhereIf(!string.IsNullOrEmpty(strFilter), x => x.user_name == strFilter || x.personal_name == strFilter)
                //.GroupJoin(userRole, x => x.user_name, y => y.user_name, (x, y) => new { x, y }).Select(o => o);
                string where = string.IsNullOrEmpty(strFilter)?"":$" AND t1.user_name like '%{strFilter}%' or t1.personal_name like '%{strFilter}%'";
                string sql = $@"with temp as (
                select t1.*,t3.role_name from  system_login  t1 left join 
                system_role_user t2 on t1.user_name = t2.user_name
                join system_role t3 ON t3.id = t2.role_id
                where t1.stop_status=0 AND t2.stop_status = 0 AND t3.stop_status = 0 {where} )
                select t1.id,t1.user_name,t1.personal_name,t1.job_number,t1.sex,t1.email,t1.register_datetime,t1.telephone,group_concat(t1.role_name) AS role_names 
                from temp t1 group  by 
                t1.id,t1.user_name,t1.personal_name,t1.job_number,t1.sex,t1.email,t1.register_datetime,t1.telephone";
                var totalCount = MySqlConn.Query(PagingHelper.CreateCountingSql(sql)).Tables[0].Rows.Count;
                //var taskList =query.PageBy(skipCount, input.pageSize).ToList();PagedResultDto
                string newSql =PagingHelper.CreatePagingSql(totalCount, input.pageSize,input.pageIndex,sql,"order by id ");
                DataTable dt = MySqlConn.Query(newSql).Tables[0];
                return new PageOutputDto<DataTable> { totalCount=totalCount, items = dt };
            }
            catch (Exception ex)
            {
                throw new UserFriendlyException(ex.Message);
            }
            
        }
        /// <summary>
        /// 【用户管理】 用户编辑：选择管理角色（可多选角色），启用操作
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string UpdateUser(UserDtoInput input)
        {
            //之前数据清掉，重新写入新的数据


            var user = _loginRepository.Get(input.id);
            if (!user.user_name.Equals(input.user_name))
            {
                throw new UserFriendlyException("参数用户名或者id传入错误");
            }
            user.stop_status = input.stop_status;
            int num = 0;
            foreach (var i in input.roleInfo)
            {
                var model = new system_role_user { role_id = i.role_id,user_name = input.user_name,add_date=DateTime.Now};
                num = _roleUserRepository.InsertAndGetId(model);
            }
            if (num > 0)
            {
                return "修改用户信息成功";
            }
            throw new UserFriendlyException("修改用户信息失败了");
        }
        #endregion
        /// <summary>
        /// 测试
        /// </summary>
        /// <returns></returns>
        public string TT()
        {
            system_login AdminInfo = AbpSessionExtension.GetObjectFromJson<system_login>(_session, DTKeys.SESSION_ADMIN_INFO);
            return "gdfgd";
        }
    }
}
